package com.wongsir.step4.tiny_ioc.xml;

import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.wongsir.step4.tiny_ioc.AbstractBeanDefinitionReader;
import com.wongsir.step4.tiny_ioc.BeanDefinition;
import com.wongsir.step4.tiny_ioc.PropertyValue;
import com.wongsir.step4.tiny_ioc.io.ResourceLoader;

/**
 * step4:读取xml配置文件来加载bean，BeanDefinitionReader的实现类
 * @author wongsir
 * @date 2018年9月14日
 */
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader{

	protected XmlBeanDefinitionReader(ResourceLoader resourceLoader) {
		super(resourceLoader);
	}

	@Override
	public void loadBeanDefinitioins(String location) throws Exception {
		InputStream inputStream = getResourceLoader().getResource(location).getInputStream();
		doLoadBeanDefinitions(inputStream);
	}

	protected void doLoadBeanDefinitions(InputStream inputStream) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = factory.newDocumentBuilder();
		Document doc = docBuilder.parse(inputStream);
		//解析bean
		registerBeanDefinitions(doc);
		inputStream.close();
	}
	
	public void registerBeanDefinitions(Document doc) {
		Element root = doc.getDocumentElement();
		
		parseBeandefinitions(root);
	}

	protected void parseBeandefinitions(Element root) {
		NodeList nl = root.getChildNodes();
		for(int i=0;i<nl.getLength();i++) {
			Node node = nl.item(i);
			if(node instanceof Element) {
				Element ele = (Element) node;
				processBeanDefinition(ele);
			}
		}
	}

	protected void processBeanDefinition(Element ele) {
		String name = ele.getAttribute("name");
		String className = ele.getAttribute("class");
		BeanDefinition beanDefinition = new BeanDefinition();
		processProperty(ele,beanDefinition);
		beanDefinition.setBeanClassName(className);
		getRegistry().put(name, beanDefinition);
	}

	private void processProperty(Element ele, BeanDefinition beanDefinition) {
		NodeList propertyNode = ele.getElementsByTagName("property");
		for(int i=0;i<propertyNode.getLength();i++) {
			Node node =propertyNode.item(i);
			if(node instanceof Element) {
				Element propertyEle = (Element)node;
				String name = propertyEle.getAttribute("name");
				String value = propertyEle.getAttribute("value");
				beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name,value));
			}
		}
	}

}
